package com.chenxi.vhr.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chenxi.vhr.bean.BaseMenu;
import com.chenxi.vhr.bean.BaseMenuRole;
import com.chenxi.vhr.bean.vo.MenuTreeVo;
import com.chenxi.vhr.bean.vo.MenuVo;
import com.chenxi.vhr.mapper.BaseMenuRoleMapper;
import com.chenxi.vhr.service.BaseMenuService;
import com.chenxi.vhr.mapper.BaseMenuMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 系统菜单
 */
@Service
public class BaseMenuServiceImpl extends ServiceImpl<BaseMenuMapper, BaseMenu>
    implements BaseMenuService {

    @Autowired
    BaseMenuMapper baseMenuMapper;

    @Autowired
    BaseMenuRoleMapper baseMenuRoleMapper;

    @Override
    public List<MenuVo> getMenuListByUserId(Integer userId) {
        return baseMenuMapper.getMenuListByUserId(userId);
    }

    @Cacheable
    @Override
    public List<MenuVo> getAllMenuWithRole() {
        return baseMenuMapper.getAllMenuWithRole();
    }

    /**
     * 【已废弃】，参考【loadMenuTreeMapInfo】方法，返回map更方便，更可读。
     * @param roleId
     * @return
     */
    @Override
    public MenuTreeVo loadMenuTreeInfo(Integer roleId) {
        MenuTreeVo vo  = new MenuTreeVo();
        vo.setChildren(baseMenuMapper.getMenuTreeBySQL());
        vo.setCheckList(baseMenuMapper.getMenuTreeCheckList(roleId));
        vo.setExpandedList(baseMenuMapper.getMenuTreeExpandedList(roleId));
        return vo;
    }

    @Override
    public Map<String, Object> loadMenuTreeMapInfo(Integer roleId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("children", baseMenuMapper.getMenuTreeBySQL());
        map.put("checkList", baseMenuMapper.getMenuTreeCheckList(roleId));
        map.put("expandedList", baseMenuMapper.getMenuTreeExpandedList(roleId));
        return map;
    }

    /**
     * 加载菜单树
     * @return
     */
    public List<MenuTreeVo> getMenuTree() {
        // 方式1:菜单层级一定：通过SQL查询
        // List<MenuTreeVo> menuTreeList = baseMenuMapper.getMenuTreeBySQL();
        // 方式2:菜单层级不定，通过递归查询
        List<MenuTreeVo> menuTreeList = new ArrayList<>();
        BaseMenu po = baseMenuMapper.selectById(1);
        MenuTreeVo vo = new MenuTreeVo();
        vo.setId(1);
        vo.setName(po.getName());
        vo.setChildren(getChildMenuListByParentMenuId(1));
        menuTreeList.add(vo);
        return menuTreeList;
    }

    @Transactional
    @Override
    public boolean updateMenuListByRoleId(Integer roleId, List<Integer> menuIdList) {
        try{
            QueryWrapper<BaseMenuRole> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("role_id", roleId);
            Integer count = baseMenuRoleMapper.selectCount(queryWrapper);
            if (count > 0) {
                baseMenuRoleMapper.delete(queryWrapper);
            }
            for (int i = 0; i < menuIdList.size(); i++) {
                BaseMenuRole entity = new BaseMenuRole();
                entity.setRoleId(roleId);
                entity.setMenuId(menuIdList.get(i));
                baseMenuRoleMapper.insert(entity);
            }
            return true;
        } catch(Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    @Override
    public Integer countMenuByRoleId(Integer roleId) {
        QueryWrapper<BaseMenuRole> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id", roleId);
        return baseMenuRoleMapper.selectCount(wrapper);
    }

    /**
     * 递归函数
     * @param menuId
     * @return
     */
    private List<MenuTreeVo> getChildMenuListByParentMenuId(int menuId) {
        QueryWrapper<BaseMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", menuId);
        queryWrapper.eq("enabled", true);
        queryWrapper.select("id,name");
        List<BaseMenu> childMenuList = baseMenuMapper.selectList(queryWrapper);
        List<MenuTreeVo> childrenList = new ArrayList<>();
        for (BaseMenu child : childMenuList) {
            MenuTreeVo childVo = new MenuTreeVo();
            childVo.setId(child.getId());
            childVo.setName(child.getName());
            childVo.setChildren(getChildMenuListByParentMenuId(child.getId()));
            childrenList.add(childVo);
        }
        return childrenList;
    }
}




